package com.dhcc.sds.util;

import cn.hutool.core.date.DateTime;
import com.dhcc.core.framework.util.CommonUtil;
import org.apache.commons.lang3.time.DateUtils;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author zhangdc
 * @version 1.0
 * @date 2021/5/12 15:07
 */
public class DateUtil {
    public static String YYYY_MM_DD = "yyyy-MM-dd";

    public static String YYYYMMDD = "yyyyMMdd";

    public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

    public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

    /**
     * 获取本月的开始时间
     * @return
     */
    public static Date getBeginDayOfMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(getNowYear(), getNowMonth() - 1, 1);
        return getDayStartTime(calendar.getTime());
    }

    /**
     * 获取本月的结束时间
     * @return
     */
    public static Date getEndDayOfMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(getNowYear(), getNowMonth() - 1, 1);
        int day = calendar.getActualMaximum(5);
        calendar.set(getNowYear(), getNowMonth() - 1, day);
        return getDayEndTime(calendar.getTime());
    }

    /**
     * 获取今年是哪一年
     * @return
     */
    public static Integer getNowYear() {
        Date date = new Date();
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        return Integer.valueOf(gc.get(1));
    }

    /**
     * 获取本月是哪一月
     * @return
     */
    public static int getNowMonth() {
        Date date = new Date();
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        return gc.get(2) + 1;
    }


    /**
     * 获取某个日期的开始时间
     * @param d
     * @return
     */
    public static Timestamp getDayStartTime(Date d) {
        Calendar calendar = Calendar.getInstance();
        if(null != d) calendar.setTime(d);
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),    calendar.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return new Timestamp(calendar.getTimeInMillis());
    }

    /**
     * 获取某个日期的结束时间
     * @param d
     * @return
     */
    public static Timestamp getDayEndTime(Date d) {
        Calendar calendar = Calendar.getInstance();
        if(null != d) calendar.setTime(d);
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),    calendar.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return new Timestamp(calendar.getTimeInMillis());
    }

    /**
     * 判断日期格式:yyyy-mm-dd
     *
     * @param sDate
     * @return
     */
    public static boolean isValidDate(String sDate) {
        if (CommonUtil.isEmpty(sDate)) {
            return false;
        }
        String datePattern1 = "\\d{4}-\\d{2}-\\d{2}";
        String datePattern2 = "^((\\d{2}(([02468][048])|([13579][26]))"
                + "[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|"
                + "(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?"
                + "((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?("
                + "(((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?"
                + "((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))";
        if ((sDate != null)) {
            Pattern pattern = Pattern.compile(datePattern1);
            Matcher match = pattern.matcher(sDate);
            if (match.matches()) {
                pattern = Pattern.compile(datePattern2);
                match = pattern.matcher(sDate);
                return match.matches();
            } else {
                return false;
            }
        }
        return false;
    }
    /**
     * 判断日期格式:yyyy-MM-dd HH:mm:ss
     *
     * @param datetime
     * @return
     */
    public static boolean isValidDateTime(String datetime){
        if (CommonUtil.isEmpty(datetime)) {
            return false;
        }
        String datePattern1 = "^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\\s(((0?[0-9])|([1][0-9])|([2][0-4]))\\:([0-5]?[0-9])((\\s)|(\\:([0-5]?[0-9])))))?$";
        Pattern pattern = Pattern.compile(datePattern1);
        return pattern.matcher(datetime).matches();
    }

    /**
     * 日期字符串转时间戳
     *
     * @param datetime
     * @return
     */
    public static long getTime(String datetime){
        if (CommonUtil.isEmpty(datetime)) {
            return 0;
        }
        String pattern = YYYY_MM_DD;
        if (isValidDate(datetime)) {
            pattern = YYYY_MM_DD;
        } else if(isValidDateTime(datetime))  {
            pattern = YYYY_MM_DD_HH_MM_SS;
        }
        SimpleDateFormat format =  new SimpleDateFormat(pattern);
        Date date = null;
        try {
            date = format.parse(datetime);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        //日期转时间戳（毫秒）
        return date.getTime();
    }

    /**
     * 计算相差多少小时或多少天或多少分钟
     * @param endDate
     * @param nowDate
     * @return
     */
    public static Long getDateCompare(Date endDate, Date nowDate, String type){
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        Long res = null;

        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - nowDate.getTime();

        if (Objects.equals("m", type)){
            //计算相差多少分钟
            res = diff / nm;
        }else if (Objects.equals("h", type)){
            //计算相差多少小时
            res = diff / nh;
        }else if (Objects.equals("d", type)){
            //计算相差多少天
            res = diff / nd;
        }

        return res;
    }

    /**
     * 得到n天前后的日期 0为当天
     *
     * @param days
     * @return
     */
    public static String getDayDate(int day,String format) {
        Calendar canlendar = Calendar.getInstance(); // java.util包
        canlendar.add(Calendar.DATE, day); // 日期减 如果不够减会将月变动
        Date date = canlendar.getTime();
        SimpleDateFormat sdfd = new SimpleDateFormat(format);
        String dateStr = sdfd.format(date);
        return dateStr;
    }

    /**
     * 格式化日期
     *
     * @return
     */
    public static Date parseTime(String date) {
        //return parse(date, YYYY_MM_DD_HH_MM_SS);
        return parse(date, YYYY_MM_DD_HH_MM_SS);
    }

    /**
     * 格式化日期
     *
     * @return
     */
    public static Date parse(String date, String pattern) {
        try {
            return DateUtils.parseDate(date, pattern);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 得到n天后日期
     * @param dateTime
     * @param day
     * @return
     */
    public static DateTime getDateByDay(DateTime dateTime, int day){
        Calendar c = Calendar.getInstance();
        c.setTime(dateTime);
        c.add(Calendar.DAY_OF_MONTH, day);
        return cn.hutool.core.date.DateUtil.date(c.getTime());
    }

    /**
     * 得到n月后日期
     * @param dateTime
     * @param month
     * @return
     */
    public static DateTime getDateByMonth(DateTime dateTime, int month){
        Calendar c = Calendar.getInstance();
        c.setTime(dateTime);
        c.add(Calendar.MONTH, month);
        return cn.hutool.core.date.DateUtil.date(c.getTime());
    }

    /**
     * 得到n年后日期
     * @param dateTime
     * @param year
     * @return
     */
    public static DateTime getDateByYear(DateTime dateTime, int year){
        Calendar c = Calendar.getInstance();
        c.setTime(dateTime);
        c.add(Calendar.YEAR, year);
        return cn.hutool.core.date.DateUtil.date(c.getTime());
    }

    /**
     * 得到指定类型n段时间前后的日期
     * @param dateTime
     * @param filterVal
     * @param filterType
     * @return
     */
    public static Date getDateByFilter(Date dateTime, int filterVal, String filterType){
        Calendar c = Calendar.getInstance();
        c.setTime(dateTime);
        if (Objects.equals("1", filterType)){
            //计算相差多少年
            c.add(Calendar.YEAR, filterVal);
        }else if (Objects.equals("2", filterType)){
            //计算相差多少月
            c.add(Calendar.MONTH, filterVal);
        }else if (Objects.equals("3", filterType)){
            //计算相差多少天
            c.add(Calendar.DAY_OF_MONTH, filterVal);
        }else if (Objects.equals("4", filterType)){
            //计算相差多少小时
            c.add(Calendar.HOUR_OF_DAY, filterVal);
        }else if (Objects.equals("5", filterType)){
            //计算相差多少分
            c.add(Calendar.MINUTE, filterVal);
        }else if (Objects.equals("6", filterType)){
            //计算相差多少秒
            c.add(Calendar.SECOND, filterVal);
        }
        return cn.hutool.core.date.DateUtil.date(c.getTime());
    }

}
